﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;
using System.Xml.Serialization;

namespace Nizm0.QOT.Library.Forms
{
    public partial class frmServerList : Form
    {
        private List<Library.Objects.Server> _serverList;
        //private Library.Objects.ProjectSettings _project;

        public List<Library.Objects.Server> ServerListDictionary
        {
            get { return _serverList; }
            set { _serverList = value; }
        }

        public frmServerList()//Library.Objects.ProjectSettings project)
        {
            InitializeComponent();
            //_serverList = LoadServerList();
            //_project = project;

            _serverList = Library.Objects.ProjectSettings.Instance.MargeConnectionSettings(LoadServerList());

            FillTheServerList();
            Library.UserControls.ucShowServerInfo serverInfo = new Library.UserControls.ucShowServerInfo();
            //serverInfo.ServerAdressChange += new Library.UserControls.ucShowServerInfo.EventChange(CheckIfServerIsOnList);
            serverInfo.Parent = groupBox_ServerInfo;
            serverInfo.Dock = DockStyle.Fill;
        }

        public static List<Library.Objects.Server> LoadServerList()
        {

            //return LoadServerList(new List<Library.Objects.Server>());
            List<Library.Objects.Server> serverlist = new List<Objects.Server>();
            //return LoadServerList(Library.Settings.Instance.ProjectSettings.Servers);
            return LoadServerList(serverlist);

        }

        public static List<Library.Objects.Server> LoadServerList(List<Library.Objects.Server> serverlist)
        {

            //MessageBox.Show(System.Reflection.Assembly.GetExecutingAssembly().Location);
            //serverlist = new List<Library.Objects.Server>();
            //FileStream fs = new FileStream(Library.Objects.Project.SettingsLocation() + "\\Servers.xml", FileMode.open);

            XmlReader tmpReader = null;

            try
            {
                string atrybutserver = string.Empty;
                string defdatabase = string.Empty;
                Library.Objects.DataBase tmpDataBase;

                if (!File.Exists(Nizm0.QOT.Settings.Instance.SettingsLocation + "\\Servers.xml"))
                {
                    CreateEmptyFile();
                    /*
                    StreamWriter sw = new StreamWriter(Library.Objects.Project.SettingsLocation() + "\\Servers.xml");
                    sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                    sw.Close();
                    */
                }
                tmpReader = XmlReader.Create(Settings.Instance.SettingsLocation + "\\Servers.xml");
                XmlDocument xmlDocument = new XmlDocument();
                xmlDocument.Load(tmpReader);

                XmlNodeList xmlListServer = xmlDocument.SelectNodes("//servers/server");


                foreach (XmlElement xmlNodeServer in xmlListServer)
                {
                    Library.Objects.Server tmpServer;
                    if (!Convert.ToBoolean(xmlNodeServer.GetAttribute("SSPI")))
                        tmpServer = new Library.Objects.Server(Convert.ToInt32(xmlNodeServer.GetAttribute("id")), xmlNodeServer.GetAttribute("address"), Convert.ToBoolean(xmlNodeServer.GetAttribute("SSPI")));
                    else
                        tmpServer = new Library.Objects.Server(Convert.ToInt32(xmlNodeServer.GetAttribute("id")), xmlNodeServer.GetAttribute("address"), Convert.ToBoolean(xmlNodeServer.GetAttribute("SSPI")), xmlNodeServer.GetAttribute("login"), xmlNodeServer.GetAttribute("password"));
                    tmpServer.Checked = Convert.ToBoolean(xmlNodeServer.GetAttribute("serverchecked"));
                    tmpServer.DataBase = new List<Library.Objects.DataBase>();

                    XmlDocument xmlDocumentServer = new XmlDocument();
                    xmlDocumentServer.LoadXml(xmlNodeServer.InnerXml);
                    foreach (XmlElement xmlNodeDatabase in xmlDocumentServer.SelectNodes("//databases/database"))
                    {
                        tmpDataBase = new Library.Objects.DataBase(xmlNodeDatabase.GetAttribute("name"));
                        tmpDataBase.Parent = tmpServer;
                        if (!tmpServer.DataBase.Exists(d => d.Name == xmlNodeDatabase.GetAttribute("name")))
                        {
                            tmpServer.DataBase.Add(tmpDataBase);
                        }
                        else
                            tmpServer.DataBase.Find(d => d.Name == xmlNodeDatabase.GetAttribute("name")).Marge(tmpDataBase);
                    }
                    if (xmlNodeServer.GetAttribute("defoultdatabase").Length > 0 && xmlNodeServer.GetAttribute("defoultdatabase").IndexOf("null", StringComparison.CurrentCultureIgnoreCase) < 0)
                    {
                        tmpServer.ActualDataBase = new Library.Objects.DataBase(xmlNodeServer.GetAttribute("defoultdatabase"));
                        if (!tmpServer.DataBase.Exists(d => d.Name == xmlNodeServer.GetAttribute("defoultdatabase")))
                            tmpServer.DataBase.Add(tmpServer.ActualDataBase);
                    }
                    tmpServer.Type = (Library.Objects.Server.TypeOfServer)Convert.ToInt32(xmlNodeServer.GetAttribute("severtype"));

                    if (!serverlist.Exists(s => s.Address == xmlNodeServer.GetAttribute("address")))
                    {
                        serverlist.Add(tmpServer);
                    }
                    //else
                    //serverlist.Find(s => s.Address == tmpServer.Address).Marge(tmpServer, true);
                }

                tmpReader.Close();
            }
            catch (Exception ex)
            {
                if (tmpReader != null)
                    tmpReader.Close();
                if (MessageBox.Show(ex.Message + Environment.NewLine + "Return backup file?", "Warning!!", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    File.Copy(Settings.Instance.SettingsLocation + "\\Servers_copy.xml", Settings.Instance.SettingsLocation + "\\Servers.xml", true);
                    serverlist = LoadServerList();
                }
            }
            return serverlist;
        }

        public static void SaveServerList()
        {
            SaveServerList(Library.Objects.ProjectSettings.Instance.Servers);
        }
        public static void SaveServerList(List<Library.Objects.Server> serverdictionary)
        {
            Serialize(serverdictionary);

            FileStream fs = new FileStream(Settings.Instance.SettingsLocation + "\\Servers.xml", FileMode.Create);
            XmlTextWriter xml = new XmlTextWriter(fs, Encoding.UTF8);
            xml.Formatting = Formatting.Indented;
            try
            {
                xml.WriteStartDocument();
                xml.WriteStartElement("QOT");
                xml.WriteStartElement("servers");
                foreach (Library.Objects.Server tmpServer in serverdictionary)
                {
                    xml.WriteStartElement("server");
                    xml.WriteAttributeString("id", tmpServer.ID.ToString());
                    xml.WriteAttributeString("address", tmpServer.Address.ToString());
                    xml.WriteAttributeString("serverchecked", tmpServer.Checked.ToString());
                    xml.WriteAttributeString("SSPI", tmpServer.SSPI.ToString());
                    if (!tmpServer.SSPI)
                    {
                        xml.WriteAttributeString("login", tmpServer.Login != null ? tmpServer.Login.ToString() : "");
                        xml.WriteAttributeString("password", tmpServer.Password != null ? tmpServer.Password.ToString() : "");
                    }
                    xml.WriteAttributeString("defoultdatabase", tmpServer.ActualDataBase != null ? tmpServer.ActualDataBase.Name.ToString() : "");
                    xml.WriteAttributeString("severtype", (((int)tmpServer.Type).ToString()));
                    xml.WriteStartElement("databases");
                    foreach (Library.Objects.DataBase tmpDataBase in tmpServer.DataBase)
                    {
                        xml.WriteStartElement("database");
                        xml.WriteAttributeString("name", tmpDataBase.Name);
                        xml.WriteEndElement();
                    }
                    xml.WriteEndElement();
                    xml.WriteEndElement();
                }
                xml.WriteEndElement();
                xml.WriteEndElement();
                xml.WriteEndDocument();

            }
            catch (Exception ex)
            {
                xml.Flush();
                fs.Close();
                if (MessageBox.Show(ex.Message + Environment.NewLine + "Try to save again?", "Warning!!", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    frmServerList.SaveServerList(serverdictionary);
            }
            finally
            {
                if (fs.CanRead)
                {
                    xml.Flush();
                    fs.Close();
                    if (File.Exists(Settings.Instance.SettingsLocation + "\\Servers_copy.xml"))
                        File.SetAttributes(Settings.Instance.SettingsLocation + "\\Servers_copy.xml", FileAttributes.Normal);
                    File.Copy(fs.Name, Settings.Instance.SettingsLocation + "\\Servers_copy.xml", true);
                    File.SetAttributes(Settings.Instance.SettingsLocation + "\\Servers_copy.xml", FileAttributes.Hidden | FileAttributes.ReadOnly);
                }
            }
        }

        private static void Serialize(List<Library.Objects.Server> serverdictionary)
        {
            try
            {
                using (StreamWriter strwr = new StreamWriter(Settings.Instance.SettingsLocation + "\\Servers_serial.xml", false))
                {
                    var settings = new XmlWriterSettings
                    {
                        Indent = true
                    };

                    var xml2 = new StringBuilder();
                    using (var writer = XmlWriter.Create(strwr, settings))
                    {
                        writer.WriteStartElement("ServerList");

                        foreach (Library.Objects.Server serv in serverdictionary)
                        {
                            var nsSerializer = new XmlSerializerNamespaces();
                            nsSerializer.Add("", "");
                            System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(serv.GetType(), "");
                            xmlSerializer.Serialize(writer, serv, nsSerializer);
                        }
                        writer.WriteEndElement();
                    }
                }
            }
            catch { }
        }

        private static void CreateEmptyFile()
        {
            FileStream fs = new FileStream(Settings.Instance.SettingsLocation + "\\Servers.xml", FileMode.Create);
            XmlTextWriter xml = new XmlTextWriter(fs, Encoding.UTF8);
            xml.Formatting = Formatting.Indented;

            xml.WriteStartDocument();
            xml.WriteStartElement("QOT");
            xml.WriteStartElement("servers");
            xml.WriteEndElement();
            xml.WriteEndElement();
            xml.WriteEndDocument();
            xml.Flush();
            fs.Close();
        }

        private void FillTheServerList()
        {
            FillTheServerList(_serverList);
        }

        private void FillTheServerList(List<Library.Objects.Server> serverlist)
        {
            foreach (Library.Objects.Server tmpServer in serverlist)
            {
                listBox_Server.Items.Add(tmpServer.Address);
            }
        }

        private void CheckIfServerIsOnList(object text)
        {
            bool found = false;
            foreach (string tmp in listBox_Server.Items)
            {
                if (tmp == text.ToString())
                {
                    if ((string)listBox_Server.SelectedItem != tmp)
                        listBox_Server.SelectedItem = tmp;
                    button_Save.Text = "Save";
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                listBox_Server.SelectedItems.Clear();
                button_Save.Text = "New";
            }
        }

        private void listBox_Server_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (listBox_Server.SelectedItem != null)
                {
                    bool found = false;
                    foreach (Control tmpControl in groupBox_ServerInfo.Controls)
                    {
                        if (tmpControl.GetType() == typeof(Library.UserControls.ucShowServerInfo))
                        {
                            ((Library.UserControls.ucShowServerInfo)tmpControl).Fill(_serverList.Find(s => s.Name == listBox_Server.SelectedItem.ToString()));
                            found = true;
                        }
                        else
                            if (tmpControl.GetType() != typeof(System.Windows.Forms.Button))
                                groupBox_ServerInfo.Controls.Remove(tmpControl);
                    }
                    if (!found)
                    {
                        Library.UserControls.ucShowServerInfo server_uc = new Library.UserControls.ucShowServerInfo(_serverList.Find(s => s.Name == (string)listBox_Server.SelectedItem));
                        //server_uc.ServerAdressChange += new Library.UserControls.ucShowServerInfo.EventChange(CheckIfServerIsOnList);
                        server_uc.Parent = groupBox_ServerInfo;
                        server_uc.Dock = DockStyle.Fill;
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void button_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void button_Ok_Click(object sender, EventArgs e)
        {
            //SaveServerList1(_serverList);
            SaveServerList(_serverList);
            this.Close();
            DialogResult = DialogResult.OK;
        }

        private void button_Save_Click(object sender, EventArgs e)
        {
            Library.Objects.Server tmpserver;
            foreach (Control tmpControl in groupBox_ServerInfo.Controls)
            {
                if (tmpControl.GetType() == typeof(Library.UserControls.ucShowServerInfo))
                {
                    tmpserver = ((Library.UserControls.ucShowServerInfo)tmpControl).ReturnServer();
                    if (_serverList.Exists(s => object.Equals(s,tmpserver)))// s.Address == tmpserver.Address))
                    {
                        //_serverList.Find(s => s.Address == tmpserver.Address).Marge(tmpserver, false);
                        //if (tmpserver.SSPI)
                        //{
                        //    _serverList.Find(s => s.Address == tmpserver.Address).SSPI = tmpserver.SSPI;
                        //}
                        //else
                        //{
                        //    _serverList.Find(s => s.Address == tmpserver.Address).SSPI = tmpserver.SSPI;
                        //    _serverList.Find(s => s.Address == tmpserver.Address).Login = tmpserver.Login;
                        //    _serverList.Find(s => s.Address == tmpserver.Address).Password = tmpserver.Password;
                        //}
                    }
                    else
                    {
                        //if (_project != null)
                        Library.Objects.ProjectSettings.Instance.Servers.Add(tmpserver);
                        listBox_Server.Items.Add(tmpserver.Address);
                    }
                    ((Library.UserControls.ucShowServerInfo)tmpControl).FeelDataBases(tmpserver);
                    //button_Save.Text = "Save";
                }
            }

        }

        private void bt_Delete_Click(object sender, EventArgs e)
        {
            if (listBox_Server.SelectedIndex >= 0)

                if (DialogResult.Yes == MessageBox.Show("Do you really whant to delete this server from global collection?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question))
                {
                    foreach (object obj in groupBox_ServerInfo.Controls)
                        if (obj.GetType() == typeof(Library.UserControls.ucShowServerInfo))
                            ((Library.UserControls.ucShowServerInfo)obj).Dispose();

                    //if (_project != null)
                    Library.Objects.ProjectSettings.Instance.Servers.RemoveAll(s => s.Name == listBox_Server.SelectedItem.ToString());
                    listBox_Server.Items.Remove(listBox_Server.SelectedItem);

                    Library.UserControls.ucShowServerInfo server_uc = new Library.UserControls.ucShowServerInfo();
                    //server_uc.ServerAdressChange += new Library.UserControls.ucShowServerInfo.EventChange(CheckIfServerIsOnList);
                    server_uc.Parent = groupBox_ServerInfo;
                    server_uc.Dock = DockStyle.Fill;
                }
        }

        private void addToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Control tmpControl in groupBox_ServerInfo.Controls)
            {
                if (tmpControl.GetType() == typeof(Library.UserControls.ucShowServerInfo))
                {
                    ((Library.UserControls.ucShowServerInfo)tmpControl).Clear();
                }
                else
                {
                    if (tmpControl.GetType() != typeof(System.Windows.Forms.Button))
                        groupBox_ServerInfo.Controls.Remove(tmpControl);

                    Library.UserControls.ucShowServerInfo server_uc = new Library.UserControls.ucShowServerInfo(_serverList.Find(s => s.Name == (string)listBox_Server.SelectedItem));
                    //server_uc.ServerAdressChange += new Library.UserControls.ucShowServerInfo.EventChange(CheckIfServerIsOnList);
                    server_uc.Parent = groupBox_ServerInfo;
                    server_uc.Dock = DockStyle.Fill;
                }
            }
        }
    }
}
